package com.wallace.downloadserver.wrapper

import com.wallace.downloadserver.myconst.DefineName
import com.wallace.downloadserver.util.FileUploadUtil
import com.wallace.downloadserver.util.myEncrypt.AESCryptUtil
import com.wallace.downloadserver.util.myEncrypt.AESKey
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import java.io.*
import javax.servlet.ServletInputStream
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletRequestWrapper

class DecryptRequestWrapper(request: HttpServletRequest) : HttpServletRequestWrapper(request) {

    private val log: Logger = LoggerFactory.getLogger(DecryptRequestWrapper::class.java)

    @Autowired
    private var fileUploadUtil: FileUploadUtil? = null

    // body明文
    private var bodyPlainByteArray: ByteArray = "".toByteArray()

    private var filePath = ""

    private val MAX_BUFFER = 4096

    private val SPECIAL_DELIMITER: ByteArray = System.getProperty("line.separator").toByteArray()

    constructor(request: HttpServletRequest, aesKey: AESKey) : this(request) {
        // 处理的不是文件
        if (!isFile()) {
            val sb = StringBuilder()
            var bufferedInputStream: BufferedInputStream? = null
            try {
                val inputStream = request.inputStream
                inputStream?.apply {
                    bufferedInputStream = BufferedInputStream(this)
                }
                bufferedInputStream?.apply {
                    val buffer = ByteArray(MAX_BUFFER)
                    var len = this.read(buffer)
                    while (len != -1) {
                        sb.append(String(buffer, 0, len))
                        len = this.read(buffer)
                    }
                    // body密文
                    val bodyCipherByteArray = sb.toString().toByteArray()
                    // AES密钥解密
                    bodyPlainByteArray = AESCryptUtil.decryptAfterDecode(bodyCipherByteArray, aesKey.getSecretKeySpec(), aesKey.iv)
                            ?: "".toByteArray()
                }
            } catch (e: IOException) {
                println("e = $e")
            } finally {
                bufferedInputStream?.close()
            }
        } else {
            var inputStream: InputStream? = null
            var outputStream: OutputStream? = null
            val tempFilePath = getFilePath()
            if (tempFilePath.isNotEmpty()) {
                try {
                    log.debug("start to receive inputStream...")
                    // 1.先接受来自客户端的文件，计算上传速度
                    inputStream = request.inputStream
                    val tempFile = File(tempFilePath)
                    outputStream = tempFile.outputStream()
                    val buffer = ByteArray(MAX_BUFFER)
                    var len = inputStream.read(buffer)
                    while (len != -1) {
                        outputStream.write(buffer.copyOfRange(0, len))
                        len = inputStream.read(buffer)
                    }
                    log.debug("end0 to receive inputStream...")
                } catch (e: IOException) {
                    filePath = ""
                    println("e = $e")
                } finally {
                    inputStream?.close()
                    outputStream?.close()
                }
            }
        }
    }

    fun isFile(): Boolean {
        if (request.contentType.contains("multipart/form-data", true)) {
            val fileName = request.getParameter("fileName")
            val part = request.getParameter("part")
            val total = request.getParameter("total")
            val md5 = (request as? HttpServletRequest)?.getHeader(DefineName.RSA_SIGNATURE)
            if (!(fileName.isNullOrEmpty()) && !(part.isNullOrEmpty()) && !(total.isNullOrEmpty()) && !(md5.isNullOrEmpty())) {
                return true
            }
        }
        return false
    }

    fun getFilePath(): String {
        if (filePath.isEmpty()) {
//            val fileName = request.getParameter("fileName")
//            val part = request.getParameter("part")
//            val total = request.getParameter("total")
            val md5 = (request as? HttpServletRequest)?.getHeader(DefineName.RSA_SIGNATURE)
            val tempFile = fileUploadUtil?.createTempFile(md5!!)
            if (tempFile != null) {
                return tempFile.absolutePath
            }
        }
        return filePath
    }

    fun getSize(): Int {
        return if (isFile()) 0 else bodyPlainByteArray.size
    }

    override fun getReader(): BufferedReader {
        return BufferedReader(InputStreamReader(inputStream))
    }

    override fun getInputStream(): ServletInputStream {
        return MyServletInputStream(ByteArrayInputStream(bodyPlainByteArray))
    }
}